package donnees.dao;

import donnees.modele.Projection;
import donnees.outils.HibernateUtil;
import java.util.Date;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

public class ProjectionDao implements ProjectionInterface {

    private Session session;

    @Override
    public void ajouterProjection(Projection p) throws Exception {
        session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        try {
            session.save(p);
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
            throw e;
            //throw new Exception("Impossible de sauvegarder la projection !");
        } finally {
            session.close();
        }
    }

    @Override
    public void modifierProjection(Projection p) throws Exception {
        session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        try {
            session.merge(p);
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
            throw new Exception("Impossible de modifier la projection !");
        } finally {
            session.close();
        }
    }

    @Override
    public void supprimerProjection(Projection p) throws Exception {
        session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = session.beginTransaction();
        try {
            session.delete(p);
            tx.commit();
        } catch (Exception e) {
            tx.rollback();
            throw new Exception("Impossible de supprimer la projection !");
        } finally {
            session.close();
        }
    }

    @Override
    public Projection trouverProjection(int id) throws Exception {
        session = HibernateUtil.getSessionFactory().openSession();
        Criteria cr = session.createCriteria(Projection.class).add(Restrictions.eq("id", id));
        Projection p = (Projection) (cr.uniqueResult());
        session.close();
        if (p == null) {
            throw new Exception("Aucune Projection ne porte cet ID.");
        } else {
            return p;
        }
    }
    
    @Override
    public Projection trouverProjection(Date date, String horaire) throws Exception {
        session = HibernateUtil.getSessionFactory().openSession();
        Criteria cr = session.createCriteria(Projection.class).add(Restrictions.eq("jour", date)).add(Restrictions.eq("heure", horaire));
        Projection p = (Projection) (cr.uniqueResult());
        session.close();
        if (p == null) {
            throw new Exception("Aucune Projection de programmée ce jour à cet horaire.");
        } else {
            return p;
        }
    }

    @Override
    public List listerProjections() throws Exception {
        session = HibernateUtil.getSessionFactory().openSession();
        List results;
        Query cr = session.createQuery("from Projection");
        results = (List) cr.list();
        session.close();
        if (results.isEmpty()) {
            throw new Exception("Impossible de lister les Projections !");
        } else {
            return results;
        }
    }
    
    @Override
    public List listerProjections(Date date) throws Exception {
        session = HibernateUtil.getSessionFactory().openSession();
        List results;
        Criteria cr = session.createCriteria(Projection.class).add(Restrictions.eq("jour", date)).addOrder(Order.asc("heure"));
        results = (List) cr.list();
        session.close();
        if (results.isEmpty()) {
            throw new Exception("Impossible de lister les Projections pour ce jour !");
        } else {
            return results;
        }
    }
    
    @Override
    public int trouverIdProjection(Projection p) throws Exception {
        int id = 0;
        session = HibernateUtil.getSessionFactory().openSession();
        Criteria cr = session.createCriteria(Projection.class).add(Restrictions.eq("jour", p.getJour())).add(Restrictions.eq("heure", p.getHeure())).setProjection(Projections.property("id"));
        id = (int) cr.uniqueResult();
        session.close();
        if (id == 0) {
            throw new Exception("Impossible de trouver l'ID de la projection !");
        } else {
            return id;
        }
    }
}
